package guide.贪心算法;

/**
 * <a href="https://leetcode-cn.com/problems/can-place-flowers">605. 种花问题</a>
 * 假设有一个很长的花坛，一部分地块种植了花，另一部分却没有。可是，花不能种植在相邻的地块上，它们会争夺水源，两者都会死去。
 * 给你一个整数数组 flowerbed 表示花坛，由若干 0 和 1 组成，其中 0 表示没种植花，1 表示种植了花。另有一个数 n ，能否在不打破种植规则的情况下种入 n 朵花？能则返回 true ，不能则返回 false。
 * 示例 1：
 *   输入：flowerbed = [1,0,0,0,1], n = 1
 *   输出：true
 * 示例 2：
 *   输入：flowerbed = [1,0,0,0,1], n = 2
 *   输出：false
 * 提示：
 *   1 <= flowerbed.length <= 2 * 104
 *   flowerbed[i] 为 0 或 1
 *   flowerbed 中不存在相邻的两朵花
 *   0 <= n <= flowerbed.length
 * @author 刘学松
 * @date 2021/2/16 22:54
 */
public class 种花问题 {
    public static void main(String[] args) {
        int[] array = {1, 0, 1, 0, 0, 1, 0};
        System.out.println(canPlaceFlowers(array, 1));
    }

    /**
     * 贪心算法实现
     * @param flowerbed
     * @param n
     * @return
     */
    public static boolean canPlaceFlowers(int[] flowerbed, int n) {
        int count = 0;
        int m = flowerbed.length;
        // 上一个1的下标
        int prev = -1;
        for (int i = 0; i < m; i++) {
            if (flowerbed[i] == 1) {
                // 遇到第一个1，加上1之前所能种的数
                if (prev < 0) {
                    count += i / 2;
                } else {
                    // 不是第一个1，则加上前一个1和当前1之间能种的数
                    count += (i - prev - 2) / 2;
                }
                // 更新1的下标为当前下标
                prev = i;
            }
        }
        // 没有遍历到1
        if (prev < 0) {
            count += (m + 1) / 2;
        } else {
            // 最后一个1，加上后面能种的数
            count += (m - prev - 1) / 2;
        }
        return count >= n;
    }

    public static boolean canPlaceFlowers1(int[] flowerbed, int n) {
        if (n == 0) {
            return true;
        }
        // 临界条件：数组长度为2n或2n-1时，最多能种n朵花
        if ((flowerbed.length + 1) / 2 < n) {
            return false;
        }
        int count = 0;
        // 标志当前位置是否能种花（具体能否种花还得看下一个位置）
        boolean flag = flowerbed[0] == 0;
        for (int i = 0; i < flowerbed.length - 1; i++) {
            // 当前位置能种且下个位置也能种
            if (flag && flowerbed[i + 1] == 0) {
                ++count;
                flag = false;
            } else {
                flag = flowerbed[i] == 0 && flowerbed[i + 1] == 0;
            }
            if (count == n) {
                return true;
            }
        }
        // 数组最后位置能种，则能种+1
        if (flag) {
            return ++count == n;
        }

        return false;
    }
}
